package server.session;

import server.*;
import server.util.LifecycleSupport;


public class StandardManager extends ManagerBase implements Lifecycle, Runnable {

    //--------------------------------------------------------------------------------------------
    protected static String name = "StandardManager";
    private static final String info = "StandardManager/1.0";

    private LifecycleSupport lifecycle = new LifecycleSupport(this);
    //检查时间间隔,单位为秒
    private int checkInterval = 60;
    private String pathname = "SESSIONS.ser";
    private boolean started = false;
    private Thread thread = null;
    //是否关闭线程
    private boolean threadDone = false;
    private String threadName = "StandardManager";
    //最大的会话数 为-1不限制
    private int maxActiveSessions = -1;

    //getter----------------------------------------------------------------------------

    public int getCheckInterval() {
        return checkInterval;
    }

    public int getMaxActiveSessions() {
        return this.maxActiveSessions;
    }

    @Override
    public String getName() {
        return name;
    }

    public String getPathname() {
        return this.pathname;
    }
    //setter----------------------------------------------------------------------------

    public void setCheckInterval(int checkInterval) {
        this.checkInterval = checkInterval;
    }

    public void setMaxActiveSessions(int max) {
        this.maxActiveSessions = max;
    }

    public void setPathname(String pathname) {
        this.pathname = pathname;
    }
    //实现Manager接口----------------------------------------------------------------------------

    @Override
    public void setContainer(Container container) {
        super.setContainer(container);
        if (this.container != null && this.container instanceof Context) {
            int sessionTimeout = ((Context) (this.container)).getSessionTimeout();
            setMaxInactiveInterval(sessionTimeout * 60);
        }
    }

    @Override
    public String getInfo() {
        return info;
    }

    @Override
    public Session createSession() {
        if (maxActiveSessions >= 0 && sessions.size() >= maxActiveSessions)
            throw new IllegalStateException("Session数超过规定的最大值");
        return super.createSession();
    }

    //实现Lifecycle接口----------------------------------------------------------------------------

    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    @Override
    public LifecycleListener[] findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    @Override
    public void start() throws LifecycleException {
        if (debug >= 1)
            log("启动中");
        if (started)
            throw new LifecycleException("Session管理器已经启动了");
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        started = true;
        threadStart();
    }

    @Override
    public void stop() throws LifecycleException {
        if (debug >= 1)
            log("停止");
        if (!started)
            throw new LifecycleException("未启动Session管理器");
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        threadStop();
        Session sessions[] = findSessions();
        for (int i = 0; i < sessions.length; i++) {
            StandardSession session = (StandardSession) sessions[i];
            if (!session.isValid())
                continue;
            try {
                session.invalidate();
            } catch (Throwable t) {

            }
        }
    }


    private void threadStart() {
        if (thread != null)
            return;
        threadDone = false;
        threadName = "StandardManager[" + container.getName() + "]";
        thread = new Thread(this, threadName);
        thread.setDaemon(true);
        thread.start();
    }
    private void threadStop() {
        if (thread == null)
            return;
        threadDone = true;
        thread.interrupt();
        try {
            thread.join();
        } catch (InterruptedException e) {

        }
        thread = null;
    }

    //实现Runnable接口
    @Override
    public void run() {
        while (!threadDone) {
            threadSleep();
            processExpiresSession();
        }
    }

    private void threadSleep() {
        try {
            Thread.sleep(checkInterval * 1000l);
        } catch (InterruptedException e) {

        }
    }

    //销毁过期Session
    private void processExpiresSession() {
        long timeNow = System.currentTimeMillis();
        Session[] sessions = findSessions();
        for (Session s : sessions) {
            StandardSession session = (StandardSession)s;
            if (!session.isValid())
                continue;
            //有效时间间隔
            int maxInactiveInterval = session.getMaxInactiveInterval();
            //一直活跃
            if (maxInactiveInterval < 0)
                return;
            int t = (int)((timeNow - session.getLastAccessedTime()) / 1000l);
            //session过期
            if (t >= maxInactiveInterval) {
                try {
                    session.invalidate();
                } catch (Throwable e) {
                    log("销毁过期Session失败", e);
                }
            }
        }
    }

}